package com.rslai.base.tool.servertest.util;

import com.rslai.base.tool.servertest.context.Context;
import com.rslai.base.tool.servertest.model.KeyValueStore;
import com.rslai.base.tool.servertest.paramfilter.FilterFactory;
import com.rslai.base.tool.servertest.response.Response;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class ParameterUtils {
    public static List<KeyValueStore> prepareParameters(List<KeyValueStore> params, Response preResult, Context context) {
        List processedParams = prepareParameters(params, preResult);
        processedParams = replaceValueFromContext(context, processedParams);
        return replaceValueFromContext(context, filter(processedParams));
    }

    private static List<KeyValueStore> prepareParameters(List<KeyValueStore> params, Response preResult) {
        for (KeyValueStore param : params) {
            replaceVariables(param, param.getValue(), preResult == null ? null : preResult.getBody());
        }
        return params;
    }

    private static void replaceVariables(Object entry, Object value, Object preResult) {
        if ((value instanceof String)) {
            String expression = value.toString();
            expression = PropertyUtils.replaceConfigValue(expression);
            ReflectionUtils.setFieldValue(entry, "value", ExtractValueUtils.replaceVariables(expression, preResult));
        }
        Iterator i$;
        if ((value instanceof Map)) {
            Map map = (Map) value;
            for (i$ = map.entrySet().iterator(); i$.hasNext(); ) {
                Object o = i$.next();
                Map.Entry item = (Map.Entry) o;
                replaceVariables(item, item.getValue(), preResult);
            }
        }
    }

    private static List<KeyValueStore> filter(List<KeyValueStore> params) {
        List result = new ArrayList(params);
        KeyValueStore param;
        for (Iterator i$ = result.iterator(); i$.hasNext(); filter(param, param.getValue())) {
            param = (KeyValueStore) i$.next();
        }

        return result;
    }

    private static void filter(Object entry, Object value) {
        if ((value instanceof List)) {
            List params = new ArrayList();
            boolean isReflect = true;
            for (Iterator i$ = ((List) value).iterator(); i$.hasNext(); ) {
                Object str = i$.next();
                if ((str instanceof KeyValueStore)) {
                    filter(str, ((KeyValueStore) str).getValue());
                    isReflect = false;
                } else if ((str instanceof String)) {
                    Object param = FilterFactory.handle(str.toString());
                    params.add(param);
                } else {
                    params.add(str);
                }
            }
            if (isReflect) {
                ReflectionUtils.setFieldValue(entry, "value", params);
            }
        }
        if ((value instanceof String)) {
            Object param = FilterFactory.handle(value.toString());
            ReflectionUtils.setFieldValue(entry, "value", param);
        }
        Iterator i$;
        if ((value instanceof Map)) {
            Map map = (Map) value;
            for (i$ = map.entrySet().iterator(); i$.hasNext(); ) {
                Object o = i$.next();
                Map.Entry item = (Map.Entry) o;
                filter(item, item.getValue());
            }
        }
    }

    public static List<KeyValueStore> replaceValueFromContext(Context context, List<KeyValueStore> processedParams) {
        List<KeyValueStore> resultList = new ArrayList(processedParams);
        for (KeyValueStore kvs : resultList) {
            Object value = kvs.getValue();
            Object result = replaceValue(value, context);
            kvs.setValue(result);
        }
        return resultList;
    }

    private static Object replaceValue(Object value, Context context) {
        if (null == value) {
            return value;
        }
        if ((value instanceof Map)) {
            return replace((Map) value, context);
        }
        if ((value instanceof List)) {
            return replace((List) value, context);
        }
        if (value.getClass().isArray()) {
            return replace(changeObjectToList(value), context).toArray();
        }
        if ((value instanceof KeyValueStore)) {
            KeyValueStore newValue = (KeyValueStore) value;
            newValue.setValue(replaceValue(newValue.getValue(), context));
            return newValue;
        }
        if ((value instanceof String)) {
            if (context == null) {
                return value;
            }
            return context.replace(value.toString());
        }
        return value;
    }

    private static List<Object> changeObjectToList(Object object) {
        List result = new ArrayList();
        if (object.getClass().isArray()) {
            int length = Array.getLength(object);
            for (int index = 0; index < length; index++)
                result.add(Array.get(object, index));
        } else {
            result.add(object);
        }
        return result;
    }

    private static Object replace(Map<Object, Object> map, Context context) {
        Map result = new LinkedHashMap(map);
        Object key;
        Object o;
        for (Iterator i$ = result.entrySet().iterator(); i$.hasNext(); result.put(key, o)) {
            java.util.Map.Entry entry = (java.util.Map.Entry) i$.next();
            key = entry.getKey();
            Object value = entry.getValue();
            o = replaceValue(value, context);
        }

        return result;
    }

    private static List<Object> replace(List<Object> list, Context context) {
        List resultList = new ArrayList(list);
        for (int index = 0; index < resultList.size(); index++) {
            Object object = resultList.get(index);
            if (!(object instanceof String)) {
                Object result = replaceValue(object, context);
                resultList.set(index, result);
            }
        }
        return resultList;
    }

    public static Map<String, String> convertListKeyValueToMap(List<KeyValueStore> list) {
        Map map = new HashMap();
        for (KeyValueStore kvs : list) {
            map.put(kvs.getName(), (String) kvs.getValue());
        }
        return map;
    }
}
